package cn.itsource.org.service.impl;

import cn.itsource.basic.query.BaseQuery;
import cn.itsource.basic.query.PageList;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.utils.RedisService;
import cn.itsource.org.domain.Department;
import cn.itsource.org.mapper.DepartmentMapper;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.org.service.IDepartmentService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department,DepartmentQuery> implements IDepartmentService {


    /**
     * zhuru redis服务
     */
    @Autowired
    private RedisService redisService;

    /**
     * 注入持久层
     */
    @Autowired
    private DepartmentMapper mapper;

/*    @Override
    public PageList<Department> getAllByPage(DepartmentQuery query) {
        // 1. 调用分页工具类设置分页参数
        PageHelper.startPage(query.getPageNum(),query.getPageSize());
        // 2. 执行查询操作
        List<Department> list = mapper.getAll(query);
        // 3. 使用pageinfo封装查询出来数据
        PageInfo<Department> pageInfo = new PageInfo<>(list);
        // 4. 使用自己的分页工具类封装分页数据
        PageList<Department> pageList = new PageList<>(pageInfo.getTotal(), pageInfo.getList());
        // 5. 返回数据
        return pageList;
    }*/


    @Override
    @CacheEvict(cacheNames = "dept",key = "'tree'")
    public void delete(Long id) {
        mapper.deleteByPrimaryKey(id);
        //redisService.deleteRedisByKey("treeList");         // 清空redis服务器中的缓存数据
    }

    @Override
    public void saveOrUpdate(Department department) {
        if(department.getId() == null) {
            // 说明id是空的，就是新增操作
            mapper.insertSelective(department);

            System.err.println("自增主键的id");
            System.err.println(department.getId());

            /**
             *    前端传过来的parents是[3,8,11,12]    需要变成   3/8/11/12/当前数据的id
             */updateDept(department);
        }

        // 6. 修改数据
        mapper.updateByPrimaryKeySelective(department);

        redisService.deleteRedisByKey("treeList");         // 清空redis服务器中的缓存数据
    }

    /**
     *    格式化前端的parentids里面的数据  【3，6，9】
     *    转换成  dirpath的字段数据     /3/6/9/当前id
     * @param department
     */
    private void updateDept(Department department) {
        // 格式化parents的数据
        // 1. 拿到parentIds数据
        Long[] parentIds = department.getParentIds();
        // 2. 判断parentIds是否为空
        if (parentIds != null && parentIds.length > 0) {
            StringBuilder sb = new StringBuilder();
            // 3. 循环parentIds
            for (int i = 0; i < parentIds.length; i++) {
                sb.append("/" + parentIds[i]);           //      /3/8/11/12
            }
            // 4.将自增主键数据写入到dirpath字段种
            department.setDirPath(sb.toString() + "/" + department.getId());
            // 5. 设置parentid字段数据
            department.setParentId(parentIds[parentIds.length - 1]);
        }
    }

    /**
     *   [
     *      {
     *          []
     *      },
     *      {}
     *   ]
     *
     *    json对象           {"key":"value"}
     *    json数组           [{"key":"value"},{"key":"value"},{"key":"value"}]
     *            json对象.get(key)
     *                    方便使用
     *
     *    json字符串       方便传输
     * @return
     *
     *    缓存的目的：
     *       避免每次查询都去mysql查
     *       将数据缓存到redis中，只要数据没有发生变化，就从redis里面直接返回
     *
     *       第一次访问需要走mysql数据库
     *       之后的每次访问都走redis
     *
     */
    @Override
    @Cacheable(cacheNames = "dept",key = "'tree'")          // SpEl    ${}     //  el表达式    ${session.username}    mybatis ${}  #{}  OGNL表达式
    public List<Department> treeDepts() {

/*        // 1. 先查询缓存服务器中的数据
        List<Department> treeList = redisService.getKeyObjectValue("treeList", List.class);
        // 2. 判空
        if (treeList == null) {
            // 2.1 查询数据库的内容
            treeList = getDepartments();
            // 2.2 将数据库中查到的内容存到redis服务器中
            redisService.setStringKeyAndValue("treeList",treeList);
        }

        // 3. 返回数据
        return treeList;*/
        System.err.println("我进来了.....");
        return getDepartments();
    }


    /**
     *    部门树方法抽取
     * @return
     */
    private List<Department> getDepartments() {
        // 1. 查询到所有的部门数据
        List<Department> departments = mapper.selectAll();
        // 2. 定义一个空集合
        List<Department> treeList = new ArrayList<>();
        // 3. 将departments数据放入一个map集合中,  方便查找
        Map<Long,Department> map = new HashMap();
        for (Department dept: departments) {
            map.put(dept.getId(),dept);
        }

        for (Department dept: departments) {
            if (dept.getParentId() == null) {
                // 表示当前数据是一个顶级父类
                treeList.add(dept);
            } else {
                // 表示当前的数据是一个子部门
                // 查找当前数据的上级部门
                Department department = map.get(dept.getParentId());
                // 将当前循环的子集部门数据放入上级部门的children中
                department.getChildren().add(dept);
            }
        }
        return treeList;
    }

    @Override
    public List<Department> getParentDepts() {
        return mapper.getParentDepts();
    }
}
